
#region Imports

using System;
using System.Collections.Generic;
using System.Text;

#endregion

namespace Justa.Messaging.Routing
{
    /// <summary>
    /// 
    /// </summary>
    /// 
    public class ContentBasedRouter<T> where T : class
    {
        /// <summary>
        /// 
        /// </summary>
        /// 
        private List<RoutingRule<T>> rules = new List<RoutingRule<T>>();

        /// <summary>
        /// 
        /// </summary>
        /// 
        private IMessageGateway<T> gateway = null;

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="sourceDestination"></param>
        /// 
        public ContentBasedRouter(string sourceDestination)
        {
            Guard.CheckForNull(sourceDestination);
            gateway = new MessageGateway<T>(sourceDestination);
            gateway.OnMessageReceived += new OnMessageEvent<T>(ApplyRoutingRules); 
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="message"></param>
        /// 
        public void ApplyRoutingRules(T message)
        {
            foreach (RoutingRule<T> rule in rules)
            {
                string[] destinations = rule.Invoke(message);
                if (Guard.IsEmpty(destinations))
                {
                    continue;
                }
                foreach (string destination in destinations)
                {
                    gateway.Send(message, destination);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="routingRule"></param>
        /// 
        public void AddRule(RoutingRule<T> routingRule)
        {
            Guard.CheckForNull(routingRule);
            rules.Add(routingRule);
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        public void Start()
        {
            gateway.StartAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        public void Stop()
        {
            gateway.StopAsync();
        }
    }
}